/**
 * Software License, Version 1.0
 * 
 * Copyright 2003 The Trustees of Indiana University.  All rights reserved.
 * 
 *
 *Redistribution and use in source and binary forms, with or without 
 *modification, are permitted provided that the following conditions are met:
 *
 *1) All redistributions of source code must retain the above copyright notice,
 * the list of authors in the original source code, this list of conditions and
 * the disclaimer listed in this license;
 *2) All redistributions in binary form must reproduce the above copyright 
 * notice, this list of conditions and the disclaimer listed in this license in
 * the documentation and/or other materials provided with the distribution;
 *3) Any documentation included with all redistributions must include the 
 * following acknowledgement:
 *
 *"This product includes software developed by the Community Grids Lab. For 
 * further information contact the Community Grids Lab at 
 * http://communitygrids.iu.edu/."
 *
 * Alternatively, this acknowledgement may appear in the software itself, and 
 * wherever such third-party acknowledgments normally appear.
 * 
 *4) The name Indiana University or Community Grids Lab or NaradaBrokering, 
 * shall not be used to endorse or promote products derived from this software 
 * without prior written permission from Indiana University.  For written 
 * permission, please contact the Advanced Research and Technology Institute 
 * ("ARTI") at 351 West 10th Street, Indianapolis, Indiana 46202.
 *5) Products derived from this software may not be called NaradaBrokering, 
 * nor may Indiana University or Community Grids Lab or NaradaBrokering appear
 * in their name, without prior written permission of ARTI.
 * 
 *
 * Indiana University provides no reassurances that the source code provided 
 * does not infringe the patent or any other intellectual property rights of 
 * any other entity.  Indiana University disclaims any liability to any 
 * recipient for claims brought by any other entity based on infringement of 
 * intellectual property rights or otherwise.  
 *
 *LICENSEE UNDERSTANDS THAT SOFTWARE IS PROVIDED "AS IS" FOR WHICH NO 
 *WARRANTIES AS TO CAPABILITIES OR ACCURACY ARE MADE. INDIANA UNIVERSITY GIVES
 *NO WARRANTIES AND MAKES NO REPRESENTATION THAT SOFTWARE IS FREE OF 
 *INFRINGEMENT OF THIRD PARTY PATENT, COPYRIGHT, OR OTHER PROPRIETARY RIGHTS. 
 *INDIANA UNIVERSITY MAKES NO WARRANTIES THAT SOFTWARE IS FREE FROM "BUGS", 
 *"VIRUSES", "TROJAN HORSES", "TRAP DOORS", "WORMS", OR OTHER HARMFUL CODE.  
 *LICENSEE ASSUMES THE ENTIRE RISK AS TO THE PERFORMANCE OF SOFTWARE AND/OR 
 *ASSOCIATED MATERIALS, AND TO THE PERFORMANCE AND VALIDITY OF INFORMATION 
 *GENERATED USING SOFTWARE.
 */
package cgl.narada.wsinfra.wsrm.storage;

import java.util.Date;

import cgl.narada.wsinfra.schemas.addressing.EndpointReferenceType;
import cgl.narada.wsinfra.schemas.soap.EnvelopeDocument;
import cgl.narada.wsinfra.wsrm.WsrmSequencePolicies;
import cgl.narada.wsinfra.wsrm.storage.impl.WsrmExchangeImpl;
import cgl.narada.wsinfra.wsrm.storage.impl.WsrmSequenceInfoImpl;
import cgl.narada.wsinfra.wsrm.storage.impl.WsrmStorageWidgetImpl;

/** This is a factory class which facilitates the creation and retrieval
    of widgets that are needed by the protocol/storage operations that
    are related to WSRM.

    @author Shrideep Pallickara
    $Date: 2005/07/29 22:41:31 $
    $Revision: 1.4 $
*/

public class WsrmStorageEventsFactory {
  private String moduleName = "WsrmStorageEventsFactory: ";
  private static final WsrmStorageEventsFactory instance = 
  new WsrmStorageEventsFactory();
  
  private WsrmStorageEventsFactory() {
    
  }
  
  public static WsrmStorageEventsFactory getInstance() {
    return instance;
  }
  
  public WsrmStorageWidget
  createWsrmStorageWidget(String sequenceIdentifier, long messageNumber, 
			  boolean acknowledgementInfo, long ackTimestampInfo,
			  EnvelopeDocument envelopeDocument)
    throws WsrmStorageException {
    
    if (sequenceIdentifier == null) {
      reportProblems("SequenceIdentifier", sequenceIdentifier);
    }
    
    if (messageNumber == 0) {
      reportProblems("MessageNumber", new Long(0));
    }

    WsrmStorageWidget storageWidget =  
      new WsrmStorageWidgetImpl(sequenceIdentifier, messageNumber, 
				acknowledgementInfo, ackTimestampInfo,
				envelopeDocument);
    return storageWidget;
  }
  

  /** Recreates a wsrm storage widget based on the bytes that were created
      using the getBytes() method in the storage widget */
  public WsrmStorageWidget 
  createWsrmStorageWidget(byte[] widgetBytes) {
    
    WsrmStorageWidget storageWidget =
      new WsrmStorageWidgetImpl(widgetBytes);
    
    return storageWidget;
  }
  


  /** Create a Wsrm Exchange based on the specified parameters */
  public WsrmExchange 
  createWsrmExchange(int exchangeType, String sequenceIdentifier,
		     EnvelopeDocument envelopeDocument) 
    throws WsrmStorageException {
    if (sequenceIdentifier == null) {
      reportProblems("SequenceIdentifier", sequenceIdentifier);
    }

    WsrmExchange wsrmExchange = 
      new WsrmExchangeImpl(exchangeType, sequenceIdentifier, envelopeDocument);
    return wsrmExchange;
  }


  /** Recreate a Wsrm Exchange from the serialized representation that has
      been specified */
  public WsrmExchange 
  createWsrmExchange(byte[] exchangeBytes) {
    WsrmExchange wsrmExchange = 
      new WsrmExchangeImpl(exchangeBytes);
    return wsrmExchange;
  }

  
  /** Creats a WsrmSequenceInfo based on the specified parameters */
  public WsrmSequenceInfo 
  createWsrmSequenceInfo(String sequenceIdentifier, 
			 String addressingIdentifier, 
			 EndpointReferenceType source, 
			 EndpointReferenceType destination,
			 boolean isSource) 
    throws WsrmStorageException {
    Date creationDate = new Date();
    if (creationDate == null) {
      reportProblems("CreationDate", creationDate);
    }
    
    if (sequenceIdentifier == null) {
      reportProblems("SequenceIdentifier", sequenceIdentifier);
    }
    
    if (addressingIdentifier == null) {
      reportProblems("AddressingIdentifier", addressingIdentifier);
    }
    
    if (source == null) {
      reportProblems("Source", source);
    }
    
    if (destination == null) {
      reportProblems("Destination", destination);
    }
    
    WsrmSequenceInfoImpl wsrmSequenceInfo = 
      new WsrmSequenceInfoImpl(creationDate, sequenceIdentifier,
			       addressingIdentifier, source, destination,
			       isSource);
    long timeNow = System.currentTimeMillis();
    wsrmSequenceInfo.setTimeOfLastActivity(timeNow);
    
    return wsrmSequenceInfo;
  }
  

  
  /** Creats a WsrmSequenceInfo based on the specified parameters */
  public WsrmSequenceInfo 
  createWsrmSequenceInfo(byte[] sequenceInfoBytes) {
    WsrmSequenceInfoImpl wsrmSequenceInfo = 
      new WsrmSequenceInfoImpl(sequenceInfoBytes);
    long timeNow = System.currentTimeMillis();
    wsrmSequenceInfo.setTimeOfLastActivity(timeNow);
    
    return wsrmSequenceInfo;
  }


  /** Attaches sequence policies to the sequence info */
  public void 
  attachPolicyToSequence(WsrmSequenceInfo wsrmSequenceInfo,
			 WsrmSequencePolicies wsrmSequencePolicies)  
    throws WsrmStorageException {
   if (wsrmSequenceInfo == null) {
      reportProblems("WsrmSequenceInfo", wsrmSequenceInfo);
   }
 
   if (wsrmSequencePolicies== null) {
     reportProblems("wsrmSequencePolicies", wsrmSequencePolicies);
   }

   WsrmSequenceInfoImpl sequenceInfo = (WsrmSequenceInfoImpl)wsrmSequenceInfo;
   sequenceInfo.setWsrmSequencePolicies(wsrmSequencePolicies);
   
  }
  
  

  /** Updates the activity on a sequence */
  public void updateActivityOnSequence(WsrmSequenceInfo wsrmSequenceInfo)  
    throws WsrmStorageException {
    if (wsrmSequenceInfo == null) {
      reportProblems("WsrmSequenceInfo", wsrmSequenceInfo);
    }
    
    WsrmSequenceInfoImpl sequenceInfo = (WsrmSequenceInfoImpl)wsrmSequenceInfo;
    long timeNow = System.currentTimeMillis();
    sequenceInfo.setTimeOfLastActivity(timeNow);
  }

  

  /** Sets information regarding the last message in a sequence */
  public void 
  setLastMessageNumberOnSequence(WsrmSequenceInfo wsrmSequenceInfo,
				 long lastMessageNumber) 
    throws WsrmStorageException {
    if (wsrmSequenceInfo == null) {
      reportProblems("WsrmSequenceInfo", wsrmSequenceInfo);
    }
    
    if (lastMessageNumber == 0) {
      reportProblems("LastMessageNumber", new Long(lastMessageNumber) );
    }
    
    WsrmSequenceInfoImpl sequenceInfo= (WsrmSequenceInfoImpl) wsrmSequenceInfo;
    sequenceInfo.setLastMessageNumber(lastMessageNumber);
  }
  
  
  
  /** Times out a sequence */
  public void timeoutSequence(WsrmSequenceInfo wsrmSequenceInfo) 
    throws WsrmStorageException {
    if (wsrmSequenceInfo == null) {
      reportProblems("WsrmSequenceInfo", wsrmSequenceInfo);
    }
    
    WsrmSequenceInfoImpl sequenceInfo=(WsrmSequenceInfoImpl) wsrmSequenceInfo;
    sequenceInfo.setTimedOut();
  } 
  

  /** Updates the sequence info to indicate that a sequence has expired. */
  public void expireSequence(WsrmSequenceInfo wsrmSequenceInfo) 
    throws WsrmStorageException {
    if (wsrmSequenceInfo == null) {
      reportProblems("WsrmSequenceInfo", wsrmSequenceInfo);
    }

    WsrmSequenceInfoImpl sequenceInfo=(WsrmSequenceInfoImpl) wsrmSequenceInfo;
    sequenceInfo.setExpired();
  }

  
  /** Updates the sequence info to indicate that a sequence has been
      terminated. */
  public void terminateSequence(WsrmSequenceInfo wsrmSequenceInfo,
				String reason)
    throws WsrmStorageException {
    if (wsrmSequenceInfo == null) {
      reportProblems("WsrmSequenceInfo", wsrmSequenceInfo);
    }

    if (reason == null) {
      reportProblems("TerminateReason", reason);
    }

    WsrmSequenceInfoImpl sequenceInfo = 
      (WsrmSequenceInfoImpl) wsrmSequenceInfo;
    sequenceInfo.setTermination(reason);
  }
  

  private void reportProblems(String element, Object elementValue)
    throws WsrmStorageException {
    throw 
      new WsrmStorageException(moduleName + "Element [" + element + 
			       "] cannot have a value of (" + 
			       elementValue +")");
  }
  
}





